from celery import shared_task
from sqlalchemy.orm import sessionmaker
from db.connection import engine
from db.repository.user_profile import UserProfileRepository
from db.repository.conversation_history import ConversationHistoryRepository
from services.prompt.prompt import PromptService
from services.prompt.emotion_templates import EmotionRecognitionTemplates
from services.prompt.personality_templates import PersonalityRecognitionTemplates
from services.llm import LLMService
from services.memo import MemoService
from utils.performance_logger import (
    log_api_call,
    log_database_operation
)
import time
from datetime import datetime

# Create database session
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)


@shared_task
def analyze_emotion_after_message(user_id: str, session_id: str, user_message: str, message_count: int = None) -> None:
    """分析单次对话后的情绪特征（每次对话后都分析）"""
    # Create database session
    db = SessionLocal()
    try:
        # 检查用户是否为访客模式
        user_profile_repo = UserProfileRepository(db)
        user_profile = user_profile_repo.get_by_user_id(user_id)
        
        if not user_profile:
            print(f"User profile not found for user {user_id}, skipping emotion analysis")
            return

        # 进行单轮情绪分析
        emotion_templates = EmotionRecognitionTemplates()
        llm_service = LLMService()
        
        emotion_result = _analyze_single_message_emotion(
            emotion_templates, llm_service, user_message, user_id
        )

        # 更新用户档案 - 将情绪结果添加到情绪列表中
        if emotion_result.get("emotion"):
            update_data = _prepare_emotion_list_update_data(emotion_result, user_profile)
            if update_data:
                user_profile_repo.update(user_profile, update_data)

        print(f"Emotion analysis completed for user {user_id} after message {message_count}")
        print(f"Emotion: {emotion_result.get('emotion', 'unknown')}")
        
    except Exception as e:
        print(f"Error in emotion analysis after message: {e}")
    finally:
        db.close()


@shared_task
def analyze_personality_after_message(user_id: str, session_id: str, message_count: int = None) -> None:
    """分析单次对话后的性格特征（每次对话后都分析）"""
    # Create database session
    db = SessionLocal()
    try:
        # 检查用户是否为访客模式
        user_profile_repo = UserProfileRepository(db)
        user_profile = user_profile_repo.get_by_user_id(user_id)
        
        if not user_profile:
            print(f"User profile not found for user {user_id}, skipping personality analysis")
            return

        # 获取对话历史
        conversation_history_repo = ConversationHistoryRepository(db)
        conversation_history = conversation_history_repo.get_by_session_id(session_id, user_id)
        
        if not conversation_history:
            print(f"No conversation history found for session {session_id}")
            return

        # 构建对话文本
        conversation_text = _build_conversation_text(conversation_history)
        
        # 进行性格分析
        personality_templates = PersonalityRecognitionTemplates()
        llm_service = LLMService()
        
        personality_result = _analyze_personality_sync(
            personality_templates, llm_service, conversation_text, user_id
        )

        # 更新用户档案
        if personality_result.get("personality"):
            update_data = _prepare_personality_update_data(personality_result)
            if update_data:
                user_profile_repo.update(user_profile, update_data)

        print(f"Personality analysis completed for user {user_id} after message {message_count}")
        print(f"Personality: {personality_result.get('personality', 'unknown')}")
        
    except Exception as e:
        print(f"Error in personality analysis after message: {e}")
    finally:
        db.close()


@shared_task
def process_conversation_end(user_id: str, session_id: str) -> None:
    """Process conversation end: analyze conversation and update user profile"""
    # Create database session
    db = SessionLocal()
    memo_service = None
    try:
        # 检查用户是否为访客模式
        user_profile_repo = UserProfileRepository(db)
        user_profile = user_profile_repo.get_by_user_id(user_id)
        is_guest_mode = user_profile is None
        
        if is_guest_mode:
            print(f"User {user_id} is in guest mode, skipping emotion and personality analysis")
            return

        # Get conversation history
        conv_history_repo = ConversationHistoryRepository(db)
        conversation_history = conv_history_repo.get_by_session_id(session_id)

        # Initialize memo service for conversation memory storage
        memo_service = MemoService()

        # Convert to list of dicts
        history_dicts = [
            {
                "user_message": item.user_message,
                "bot_response": item.bot_response,
                "image_url": item.image_url,
                "intent": item.intent,
            }
            for item in conversation_history
        ]

        # Store conversation in memo service
        if history_dicts:
            messages = []
            for conv in history_dicts:
                if conv.get("user_message"):
                    messages.append({"role": "user", "content": conv["user_message"]})
                if conv.get("bot_response"):
                    messages.append(
                        {"role": "assistant", "content": conv["bot_response"]}
                    )

            if messages:
                metadata = {
                    "session_id": session_id,
                    "conversation_count": len(history_dicts),
                    "has_images": any(conv.get("image_url") for conv in history_dicts),
                    "intents": [
                        conv.get("intent")
                        for conv in history_dicts
                        if conv.get("intent")
                    ],
                }

                try:
                    memo_service.add_memory(messages, user_id, metadata)
                    print(f"Conversation stored in memo service for user {user_id}")
                except Exception as e:
                    print(f"Error storing conversation in memo service: {e}")

        # Summarize conversation (保持原有功能)
        prompt_service = PromptService()
        # summary = prompt_service.summarize_conversation(history_dicts)

        # 新增：情绪和性格分析
        conversation_text = _build_conversation_text(history_dicts)
        emotion_templates = EmotionRecognitionTemplates()
        personality_templates = PersonalityRecognitionTemplates()
        llm_service = LLMService()

        emotion_result = _analyze_emotion_sync(
            emotion_templates, llm_service, conversation_text, user_id
        )
        personality_result = _analyze_personality_sync(
            personality_templates, llm_service, conversation_text, user_id
        )

        # Update user profile (合并原有摘要和新的分析结果)
        user_profile_repo = UserProfileRepository(db)
        user_profile = user_profile_repo.get_by_user_id(user_id)

        if user_profile:
            # 准备更新数据
            update_data = _prepare_profile_update_data(
                emotion_result, personality_result
            )
            if update_data:
                user_profile_repo.update(user_profile, update_data)

        print(f"Processed conversation end for user {user_id}, session {session_id}")
        print(f"Emotion analysis: {emotion_result.get('emotion', 'unknown')}")
        print(
            f"Personality analysis: {personality_result.get('personality', 'unknown')}"
        )
    finally:
        db.close()
        if memo_service:
            memo_service.close()


def _build_conversation_text(conversation_history: list) -> str:
    """构建对话文本"""
    text_parts = []
    for conv in conversation_history:
        user_msg = conv.get("user_message", "")
        bot_resp = conv.get("bot_response", "")
        if user_msg:
            text_parts.append(f"用户: {user_msg}")
        if bot_resp:
            text_parts.append(f"机器人: {bot_resp}")

    return "\n".join(text_parts)


def _analyze_single_message_emotion(
    emotion_templates, llm_service, user_message: str, user_id: str
) -> dict:
    """分析单条消息的情绪"""
    try:
        # 生成情绪识别提示词
        prompt = emotion_templates.build_single_message_emotion_prompt(
            user_message=user_message, user_id=user_id
        )

        # 调用LLM进行分析
        messages = [
            {"role": "system", "content": "你是情绪识别专家，请严格按照JSON格式返回分析结果。"},
            {"role": "user", "content": prompt},
        ]

        # 记录情绪分析LLM调用
        log_api_call(
            api_name="SINGLE_MESSAGE_EMOTION_ANALYSIS",
            api_type="LLM",
            request_data={
                "user_id": user_id,
                "message_length": len(user_message),
                "prompt_length": len(prompt)
            }
        )

        result = llm_service.chat_completion(messages)

        if not result:
            # 如果LLM调用失败，使用备选方法
            print(f"LLM单轮情绪识别失败，使用备选方法")
            return emotion_templates.analyze_single_message_only(
                user_message=user_message, user_id=user_id
            )

        # 尝试从LLM响应中提取情绪数据
        extracted = emotion_templates.extract_emotion_from_text(
            text=result, user_id=user_id
        )

        # 验证数据
        validated = emotion_templates.validate_emotion_data(extracted)
        extracted["validation"] = validated

        return extracted

    except Exception as e:
        print(f"单轮情绪识别分析失败: {e}")
        # 返回备选分析结果
        return emotion_templates.analyze_single_message_only(
            user_message=user_message, user_id=user_id
        )


def _analyze_emotion_sync(
    emotion_templates, llm_service, conversation_text: str, user_id: str
) -> dict:
    """同步分析情绪（Celery任务中使用）"""
    try:
        # 生成情绪识别提示词
        prompt = emotion_templates.build_emotion_recognition_prompt(
            conversation=conversation_text, user_id=user_id
        )

        # 调用LLM进行分析
        messages = [
            {"role": "system", "content": "你是情绪识别专家，请严格按照JSON格式返回分析结果。"},
            {"role": "user", "content": prompt},
        ]

        # 记录情绪分析LLM调用
        log_api_call(
            api_name="EMOTION_ANALYSIS",
            api_type="LLM",
            request_data={
                "user_id": user_id,
                "conversation_length": len(conversation_text),
                "prompt_length": len(prompt)
            }
        )

        result = llm_service.chat_completion(messages)

        if not result:
            # 如果LLM调用失败，使用备选方法
            print(f"LLM情绪识别失败，使用备选方法")
            return emotion_templates.analyze_conversation_only(
                conversation=conversation_text, user_id=user_id
            )

        # 尝试从LLM响应中提取情绪数据
        extracted = emotion_templates.extract_emotion_from_text(
            text=result, user_id=user_id
        )

        # 验证数据
        validated = emotion_templates.validate_emotion_data(extracted)
        extracted["validation"] = validated

        return extracted

    except Exception as e:
        print(f"情绪识别分析失败: {e}")
        # 返回备选分析结果
        return emotion_templates.analyze_conversation_only(
            conversation=conversation_text, user_id=user_id
        )


def _analyze_personality_sync(
    personality_templates, llm_service, conversation_text: str, user_id: str
) -> dict:
    """同步分析性格（对话结束时进行性格识别）"""
    try:
        # 生成性格识别提示词
        prompt = personality_templates.build_personality_recognition_prompt(
            conversation=conversation_text, user_id=user_id
        )

        # 调用LLM进行分析
        messages = [
            {"role": "system", "content": "你是性格识别专家，请严格按照JSON格式返回分析结果。"},
            {"role": "user", "content": prompt},
        ]

        # 记录性格分析LLM调用
        log_api_call(
            api_name="PERSONALITY_ANALYSIS",
            api_type="LLM",
            request_data={
                "user_id": user_id,
                "conversation_length": len(conversation_text),
                "prompt_length": len(prompt),
                "analysis_type": "conversation_end"
            }
        )

        result = llm_service.chat_completion(messages)

        if not result:
            # 如果LLM调用失败，使用备选方法
            print(f"LLM性格识别失败，使用备选方法")
            return personality_templates.analyze_conversation_only(
                conversation=conversation_text, user_id=user_id
            )

        # 尝试从LLM响应中提取性格数据
        extracted = personality_templates.extract_personality_from_text(
            text=result, user_id=user_id
        )

        # 验证数据
        validated = personality_templates.validate_personality_data(extracted)
        extracted["validation"] = validated

        print(f"对话结束性格识别完成: {extracted.get('personality', 'unknown')}")
        return extracted

    except Exception as e:
        print(f"性格识别分析失败: {e}")
        # 返回备选分析结果
        return personality_templates.analyze_conversation_only(
            conversation=conversation_text, user_id=user_id
        )


def _prepare_emotion_list_update_data(emotion_result: dict, user_profile) -> dict:
    """准备情绪列表更新数据"""
    update_data = {}
    
    # 获取现有的情绪列表
    existing_emotions = []
    if hasattr(user_profile, 'emotion_list') and user_profile.emotion_list:
        try:
            import json
            existing_emotions = json.loads(user_profile.emotion_list) if isinstance(user_profile.emotion_list, str) else user_profile.emotion_list
        except:
            existing_emotions = []
    
    # 添加新的情绪结果到列表
    if emotion_result.get("emotion"):
        new_emotion_entry = {
            "emotion": emotion_result.get("emotion"),
            "primary_emotion": emotion_result.get("primary_emotion"),
            "intensity": emotion_result.get("intensity", 5),
            "confidence": emotion_result.get("confidence", 0.5),
            "timestamp": emotion_result.get("analysis_timestamp", ""),
            "description": emotion_result.get("description", "")
        }
        existing_emotions.append(new_emotion_entry)
        
        # 限制情绪列表长度，只保留最近50条记录
        if len(existing_emotions) > 50:
            existing_emotions = existing_emotions[-50:]
        
        update_data["emotion_list"] = json.dumps(existing_emotions, ensure_ascii=False)
        
        # 更新当前情绪
        update_data["current_emotion"] = emotion_result.get("emotion")
        
        # 更新情绪连续性描述
        update_data["emotional_continuity"] = f"当前情绪: {emotion_result.get('emotion')} (强度: {emotion_result.get('intensity', 5)}/10)"

    return update_data


def _prepare_personality_update_data(personality_result: dict) -> dict:
    """准备性格分析更新数据"""
    update_data = {}
    
    # 性格相关字段 - 基于完整对话的性格识别结果
    if personality_result.get("personality"):
        # 构建详细的性格描述
        personality_text = f"主要性格: {personality_result['personality']}"
        
        # 添加性格特征信息
        if personality_result.get("personality_traits"):
            traits = personality_result["personality_traits"]
            if traits.get("secondary_traits"):
                personality_text += f", 次要特征: {', '.join(traits['secondary_traits'])}"
            if traits.get("strength_level"):
                personality_text += f", 强度: {traits['strength_level']}/10"
        
        # 添加置信度信息
        if personality_result.get("confidence"):
            personality_text += f", 置信度: {personality_result['confidence']:.2f}"
        
        # 添加分析时间戳
        if personality_result.get("analysis_timestamp"):
            personality_text += f", 分析时间: {personality_result['analysis_timestamp']}"

        update_data["personality"] = personality_text

    # MBTI人格模型 - 存储完整的性格分析数据
    if personality_result.get("personality"):
        mbti_data = {
            "personality_type": personality_result.get("personality"),
            "confidence": personality_result.get("confidence", 0.0),
            "personality_traits": personality_result.get("personality_traits", {}),
            "behavior_analysis": personality_result.get("behavior_analysis", {}),
            "profile_update": personality_result.get("profile_update", {}),
            "analysis_timestamp": personality_result.get("analysis_timestamp"),
            "conversation_rounds": personality_result.get("conversation_rounds", 0),
            "reasoning": personality_result.get("reasoning", ""),
            "validation": personality_result.get("validation", {}),
        }
        update_data["personality"] = mbti_data

    return update_data


def _prepare_profile_update_data(
    emotion_result: dict, personality_result: dict
) -> dict:
    """准备用户档案更新数据（针对完整对话的性格识别结果）"""
    update_data = {}

    # 情绪相关字段
    if emotion_result.get("emotion"):
        update_data["current_emotion"] = emotion_result["emotion"]

    # 情绪轮数据
    if emotion_result.get("conversation_analysis") or emotion_result.get(
        "image_analysis"
    ):
        emotion_wheel_data = {
            "emotion_type": emotion_result.get("emotion"),
            "confidence": emotion_result.get("confidence"),
            "conversation_analysis": emotion_result.get("conversation_analysis", {}),
            "image_analysis": emotion_result.get("image_analysis", {}),
            "profile_update": emotion_result.get("profile_update", {}),
        }
        update_data["plutchik_emotion_wheel"] = emotion_wheel_data

    # 情绪连续性
    if emotion_result.get("emotion"):
        update_data["emotional_continuity"] = f"当前情绪: {emotion_result['emotion']}"

    # 性格相关字段 - 基于完整对话的性格识别结果
    if personality_result.get("personality"):
        # 构建详细的性格描述
        personality_text = f"主要性格: {personality_result['personality']}"
        
        # 添加性格特征信息
        if personality_result.get("personality_traits"):
            traits = personality_result["personality_traits"]
            if traits.get("secondary_traits"):
                personality_text += f", 次要特征: {', '.join(traits['secondary_traits'])}"
            if traits.get("strength_level"):
                personality_text += f", 强度: {traits['strength_level']}/10"
        
        # 添加置信度信息
        if personality_result.get("confidence"):
            personality_text += f", 置信度: {personality_result['confidence']:.2f}"
        
        # 添加分析时间戳
        if personality_result.get("analysis_timestamp"):
            personality_text += f", 分析时间: {personality_result['analysis_timestamp']}"

        update_data["personality"] = personality_text

    # MBTI人格模型 - 存储完整的性格分析数据
    if personality_result.get("personality"):
        mbti_data = {
            "personality_type": personality_result.get("personality"),
            "confidence": personality_result.get("confidence", 0.0),
            "personality_traits": personality_result.get("personality_traits", {}),
            "behavior_analysis": personality_result.get("behavior_analysis", {}),
            "profile_update": personality_result.get("profile_update", {}),
            "analysis_timestamp": personality_result.get("analysis_timestamp"),
            "conversation_rounds": personality_result.get("conversation_rounds", 0),
            "reasoning": personality_result.get("reasoning", ""),
            "validation": personality_result.get("validation", {}),
        }
        update_data["personality"] = mbti_data

    # 交互风格 - 基于性格识别结果
    if personality_result.get("personality"):
        interaction_style = f"基于{personality_result['personality']}性格的交互风格"
        if personality_result.get("personality_traits", {}).get("interaction_preference"):
            interaction_style += f", 偏好: {personality_result['personality_traits']['interaction_preference']}"
        update_data["interaction_style"] = interaction_style

    # 情感表达方式 - 基于性格特征
    if personality_result.get("personality_traits", {}).get("emotional_expression"):
        update_data["emotional_expression_style"] = personality_result["personality_traits"]["emotional_expression"]

    print(f"用户档案更新数据准备完成: {len(update_data)} 个字段")
    return update_data
